package com.cly.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cly.model.SmsModel;
import com.cly.constant.PhoneConstant;
import com.cly.constant.QueueConstant;
import com.cly.domain.User;
import com.cly.mapper.UserMapper;
import com.cly.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private UserMapper userMapper;

    /**
     * 更新用户信息
     * @param user
     * @return
     */
    @Override
    public boolean updateById(User user) {
        //更新时间
        //ip
        user.setModifyTime(new Date());
        user.setUserLasttime(new Date());
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = request.getRemoteHost();
        user.setUserLastip(ip);
        return super.updateById(user);
    }

    /**
     * 发送短信验证
     * 1.生成一个验证码
     * 2.存入redis 设置过期时间
     * 3.组装发送对象
     * 4.放入mq
     *
     * @param map
     */
    @Override
    public void send(Map<String, String> map) {
        String code = createCode();
        String phonenum = map.get("phonenum");
        if (StringUtils.isEmpty(phonenum)){
            throw new IllegalArgumentException("发送短信时手机号不能为空");
        }
        //存入redis
        redisTemplate.opsForValue().set(PhoneConstant.PHONE_PREFIX + phonenum, code, Duration.ofSeconds(5));
        //组装对象 放入mq
        HashMap<String, Object> data = new HashMap<>(4);
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        data.put("userId",userId);
        SmsModel smsModel = new SmsModel();
        smsModel.setPhoneNumbers(phonenum);
        smsModel.setSignName("ego商城");
        smsModel.setTemplateCode("SMS_203185255");
        //占位符
        HashMap<String, String> codeMap = new HashMap<>(2);
        codeMap.put("code",code);
        smsModel.setTemplateCode(JSON.toJSONString(codeMap));
        data.put("smsModel",smsModel);
        //放入mq
        rabbitTemplate.convertAndSend(QueueConstant.PHONE_SMS_EX,QueueConstant.PHONE_SMS_KEY,JSON.toJSONString(data));
        log.info("短信放入mq");

    }

    /**
     * 保存手机号
     * 1.拿到手机号
     * 2.拿到验证码
     * 3.和redis做对比
     * 4.拿到当前用户
     * 5.跟新数据库
     * @param map
     */
    @Override
    public void savePhone(Map<String, String> map) {
        String phonenum = map.get("phonenum");
        String code = map.get("code");
        //和redis比较
        String realCode = redisTemplate.opsForValue().get(PhoneConstant.PHONE_PREFIX + phonenum);
        if (StringUtils.hasText(realCode) && realCode.equals(code)){
            //成功
            String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
            User user = new User();
            user.setUserMobile(phonenum);
            user.setModifyTime(new Date());
            userMapper.update(user, new LambdaQueryWrapper<User>()
                    .eq(User::getUserId, userId)
            );
            log.info("记录用户手机号成功");
        }
    }

    /**
     * 验证码
     * @return
     */
    private String createCode() {
        return "6666";
    }
}
